#include "Signal.h"
#include "Source.h"

// #######################################################################
source_fromfile::source_fromfile(const char* filename)
{
#ifdef DEBUG
  cout << "source_fromfile::source_fromfile()\n";
#endif
  int Dim_Input[1] = {0};
  int Dim_Output[1] = {1};
  block::initialize(0,Dim_Input,1,Dim_Output,0.0);
  
  fin.open(filename,ios_base::in);
  if(!fin.is_open())
  {
    cout << "\nUnable to open input file " << filename;
    system("pause");
    exit(1);
  }
  else
  {
    cout << "\n -------------------------";
    cout << "\nClass: source_fromfile";
    cout << "\n  filename = " << filename;
    cout << "\n -------------------------\n";
  }

  // Read all data
  double time_value;
  double signal_value;
  string temp;
  t_node = 0;
  // Skip the column name on the first row
  fin >> temp;
  fin >> temp;
  while(!fin.eof())
  {
    fin >> time_value;
    time.push_back(time_value);
    fin >> signal_value;
    signal.push_back(signal_value);
    ++t_node;
  }

  t_idx = 0;
  // 0<= t_idx < t_node
#ifdef DEBUG
  cout << "END source_fromfile::source_fromfile()\n";
#endif
}
// -------------------------------------------
source_fromfile::~source_fromfile(){
#ifdef DEBUG
  cout << "source_fromfile::~source_fromfile()\n";
#endif
  fin.close();
#ifdef DEBUG
  cout << "END source_fromfile::~source_fromfile()\n";
#endif
}
// -------------------------------------------
void source_fromfile::update(double time_sys){
  if(time_sys<time[t_idx]){
    cerr << "Error@source_fromfile::update(), time_sys = " << time_sys << ", time = " << time[t_idx] << "\n";
    exit(1);
  }
  else{
    while(t_idx < t_node && (time[t_idx+1]<=time_sys)){
      ++t_idx;
    }
    outputs[0][0] = signal[t_idx];
  }
}
// -------------------------------------------
void source_fromfile::reset(){
  t_idx = 0;
}
// #######################################################################



// #######################################################################
source_constant::source_constant(double iValue){
#ifdef DEBUG
  cout << "source_constant::source_constant()\n";
#endif
  value = iValue;
  int Dim_Input[1] = {0};
  int Dim_Output[1] = {1};
  block::initialize(0,Dim_Input,1,Dim_Output,0.0);
  outputs[0][0] = value;
#ifdef DEBUG
  cout << "END source_constant::source_constant()\n";
#endif
}

source_constant::~source_constant(){
#ifdef DEBUG
  cout << "source_constant::~source_constant()\n";
  cout << "END source_constant::~source_constant()\n";
#endif
}

void source_constant::reset(){
  time = 0.0;
}
void source_constant::update(const double time_sys){
  return;
}
// #######################################################################



// #######################################################################
source_sin::source_sin(const double in){
  n = in;
}

double source_sin::update(const double time_sys){
  return sin(n*time_sys);
}
// #######################################################################
source_squarewave::source_squarewave(const double iPeriod, const double iRatio)
{
  period = iPeriod;
  ratio = iRatio;
}

double source_squarewave::update(const double time_sys)
{
  double TimeInPeriod;
  TimeInPeriod = fmod(time_sys,period);
  if(TimeInPeriod < ratio*period)
    return 1.0;
  else
    return 0.0;
}
// #######################################################################
source_whitenoise::source_whitenoise(const double iSigma2){

}
// #######################################################################
source_sin_spatial::source_sin_spatial(double iXYmax,int iL,
				       double iMean, double iA,double ik)
{
  XYmax = iXYmax;
  L = iL;
  mean = iMean;
  A = iA;
  k = ik;

  int Dim_Input[1] = {0};
  int Dim_Output[1];
  Dim_Output[0] = L*L;
  block::initialize(0,Dim_Input,1,Dim_Output,0.0);
  int ix,iy,i;
  for(iy=0;iy<L;iy++){
    for(ix=0;ix<L;ix++){
      i = iy*L+ix;
      outputs[0][i] = mean+A*sin(2*k*pi*ix/L);
    }
  }
}

source_sin_spatial::~source_sin_spatial(){
}

void source_sin_spatial::update(const double time_sys){
  return;
}
// ######################################################################
